﻿using MiniFox.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace MiniFox.Data
{
    /// <summary>
    /// 
    /// </summary>
    public interface IDataProvider
    {
        /// <summary>
        /// 
        /// </summary>
        event EventHandler<DataOperatingEventArgs> DataBatchExecuting;
        /// <summary>
        /// 
        /// </summary>
        event EventHandler<DataOperatedEventArgs> DataBatchExecuted;

        /// <summary>
        /// 
        /// </summary>
        event EventHandler<DataOperatingEventArgs> DataInserting;
        /// <summary>
        /// 
        /// </summary>
        event EventHandler<DataOperatedEventArgs> DataInserted;

        /// <summary>
        /// 
        /// </summary>
        event EventHandler<DataOperatingEventArgs> DataUpdating;
        /// <summary>
        /// 
        /// </summary>
        event EventHandler<DataOperatedEventArgs> DataUpdated;

        /// <summary>
        /// 
        /// </summary>
        event EventHandler<DataOperatingEventArgs> DataDeleting;
        /// <summary>
        /// 
        /// </summary>
        event EventHandler<DataOperatedEventArgs> DataDeleted;

        /// <summary>
        /// 
        /// </summary>
        event EventHandler<DataLoadedEventArgs> DataLoaded;

        #region 添加
        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entites"></param>
        int Insert<T>(params T[] entites) where T : class;
        
        #endregion

        #region 修改
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entites"></param>
        int Update<T>(params T[] entites) where T : class;
        
        #endregion

        #region 删除
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entites"></param>
        int Delete<T>(params T[] entites) where T : class;

        #endregion

        #region 获取查询对象
        /// <summary>
        /// 
        /// </summary>
        DataSourceFactory DataSourceFactory { get; }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IDataQuery<T> GetDataQuery<T>() where T : class;

        #endregion

        #region QueryExecute
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        ResultSet QueryExecute(string name, IQueryObject request);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        ResultSet QueryExecute(string name, object parameters);

        #endregion

        #region QueryExecute~T
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="request"></param>
        /// <returns></returns>
        ResultSet<TEntity> QueryExecute<TEntity>(IQueryObject request) where TEntity : class;
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        ResultSet<TEntity> QueryExecute<TEntity>(IQueryable<TEntity> queryable, IQueryObject request) where TEntity : class;

        #endregion

        #region PagedQueryExecute
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        PagedResultSet PagedQueryExecute(string name, IPagedQueryObject request);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="parameters"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sortFields"></param>
        /// <returns></returns>
        PagedResultSet PagedQueryExecute(string name, object parameters, int pageIndex, int pageSize, IDictionary<string, bool> sortFields);
        #endregion

        #region PagedQueryExecute~T
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="request"></param>
        /// <returns></returns>
        PagedResultSet<TEntity> PagedQueryExecute<TEntity>(IPagedQueryObject request) where TEntity : class;
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        PagedResultSet<TEntity> PagedQueryExecute<TEntity>(IQueryable<TEntity> queryable, IPagedQueryObject request) where TEntity : class;
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="expression"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sortFields"></param>
        /// <returns></returns>
        PagedResultSet<TEntity> PagedQueryExecute<TEntity>(Expression<Func<TEntity, bool>> expression, int pageIndex, int pageSize, IDictionary<string, bool> sortFields) where TEntity : class;
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="expression"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sortFields"></param>
        /// <returns></returns>
        PagedResultSet<TEntity> PagedQueryExecute<TEntity>(IQueryable<TEntity> queryable, Expression<Func<TEntity, bool>> expression, int pageIndex, int pageSize, IDictionary<string, bool> sortFields) where TEntity : class;
        #endregion
    }

    /// <summary>
    /// 
    /// </summary>
    public class DataOperatingEventArgs : EventArgs
    {
        object[] _data;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        public DataOperatingEventArgs(params object[] data)
        {
            _data = data;
        }
        /// <summary>
        /// 
        /// </summary>
        public object[] Data
        {
            get { return _data; }
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class DataLoadedEventArgs : EventArgs
    {
        object _data;
        /// <summary>
        /// 
        /// </summary>
        public DataLoadedEventArgs(object data)
        {
            _data = data;
        }
        /// <summary>
        /// 
        /// </summary>
        public object Data
        {
            get { return _data; }
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class DataOperatedEventArgs : EventArgs
    {
        object[] _data;
        bool _success;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="success"></param>
        /// <param name="data"></param>
        public DataOperatedEventArgs(bool success, params object[] data)
        {
            _data = data;
            _success = success;
        }
        /// <summary>
        /// 
        /// </summary>
        public bool Success
        {
            get { return _success; }
        }
        /// <summary>
        /// 
        /// </summary>
        public object[] Data
        {
            get { return _data; }
        }
    }
}
